package com.woniuxy.yoga.progress.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.yoga.commons.core.model.Result;
import com.woniuxy.yoga.commons.core.statedata.UserState;
import com.woniuxy.yoga.commons.redis.util.rediskeyutil.CourseRedisKeyUtil;
import com.woniuxy.yoga.progress.client.OrderClient;
import com.woniuxy.yoga.progress.client.UserClient;
import com.woniuxy.yoga.progress.dao.model.Lifecard;
import com.woniuxy.yoga.progress.dao.mapper.LifecardMapper;
import com.woniuxy.yoga.progress.model.dto.OrderInfoDto;
import com.woniuxy.yoga.progress.model.dto.UserInfoDto;
import com.woniuxy.yoga.progress.model.exception.ProgressException;
import com.woniuxy.yoga.progress.model.exception.ProgressExceptionCode;
import com.woniuxy.yoga.progress.model.param.CreateLifeCardParam;
import com.woniuxy.yoga.progress.service.LifecardService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;
import java.util.concurrent.TimeUnit;


/**
 * <p>
 * 终身卡流程表 服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@Service
public class LifecardServiceImpl extends ServiceImpl<LifecardMapper, Lifecard> implements LifecardService {

    @Autowired
    private LifecardMapper lifecardMapper;

    @Autowired
    private OrderClient orderClient;

    @Autowired
    private UserClient userClient;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 通过用户id查询终身卡进度
     * @param userId 用户id
     * @return Lifecard
     */
    @Override
    public Lifecard getByUserId(Integer userId) {
        QueryWrapper<Lifecard> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        Lifecard lifecard = lifecardMapper.selectOne(wrapper);
        if(lifecard==null) throw new ProgressException(ProgressExceptionCode.PROGRESS_EXCEPTION_CODE_NO_CARD);
        return lifecard;
    }

    /**
     * 创建终身卡进度表
     * @param param 创建终身卡进度表参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createLifeCard(CreateLifeCardParam param) {
        //查询是否重复添加进度
        QueryWrapper<Lifecard> wrapper = new QueryWrapper<>();
        wrapper.eq("order_num",param.getOrderNum());
        Lifecard lifecard = lifecardMapper.selectOne(wrapper);
        if (lifecard!=null) throw new ProgressException(ProgressExceptionCode.PROGRESS_EXCEPTION_CODE_CARD_REPEAT);
        //查询是否用户是否重复购买
        QueryWrapper<Lifecard> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("user_id",param.getUserId());
        Lifecard lifecard1 = lifecardMapper.selectOne(wrapper1);
        if (lifecard1!=null) throw new ProgressException(ProgressExceptionCode.PROGRESS_EXCEPTION_CODE_CARD_REPEAT);
        //创建进度表对象
        Lifecard card = new Lifecard();
        card.setOrderNum(param.getOrderNum());
        card.setUserId(param.getUserId());
        card.setLearnCount(0);
        lifecardMapper.insert(card);
    }

    /**
     * 转让终身卡
     * @param transUserId 转入id
     * @param userId 转出id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transformLifeCard(Integer transUserId, Integer userId) {
        //查询转出用户是否正常
        QueryWrapper<Lifecard> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        Lifecard lifecard = lifecardMapper.selectOne(wrapper);
        if (lifecard==null) throw new ProgressException(ProgressExceptionCode.PROGRESS_EXCEPTION_CODE_CARD_NOT_EXIST);
        //查询是否已经转让过,查询订单userId,如果与当前转出id不同，则已经转让过，不可再次转让
        Result<OrderInfoDto> result = orderClient.getByOrderNum(lifecard.getOrderNum());
        if (result.getCode()!=200) throw new ProgressException(result.getCode(),result.getMessage());
        OrderInfoDto orderInfoDto = result.getData();
        if (!Objects.equals(orderInfoDto.getUserId(), userId)) throw new ProgressException(ProgressExceptionCode.PROGRESS_EXCEPTION_CODE_LIFE_CARD_TRANSFORMED);
        //查询被转入id是否正常
        Result<UserInfoDto> userResult = userClient.getByUserId(transUserId);
        if (userResult.getCode()!=200) throw new ProgressException(userResult.getCode(),userResult.getMessage());
        if (!Objects.equals(userResult.getData().getUserState(), UserState.USER_ACCOUNT_STATE_NORMAL))
            throw new ProgressException(ProgressExceptionCode.PROGRESS_EXCEPTION_CODE_USER_STATE_WRONG);
        //转让终身卡
        lifecard.setUserId(transUserId);
        lifecardMapper.updateById(lifecard);
    }

    /**
     * 终身卡次数加一
     * @param lifecardId 终身卡id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addLifeCardCount(Integer lifecardId) throws Exception{
        //创建单锁
        RLock lock = redissonClient.getFairLock(CourseRedisKeyUtil.lockCurrentCountByCourseId(lifecardId));
        boolean isLock = lock.tryLock(10, TimeUnit.SECONDS);
        try {
            if (!isLock){
                throw new Exception("服务器繁忙请稍后再试");
            }
            //判断卡是否存在
            Lifecard lifecard = lifecardMapper.selectById(lifecardId);
            if (lifecard == null) throw new ProgressException(ProgressExceptionCode.PROGRESS_EXCEPTION_CODE_CARD_NOT_EXIST);
            //次数+1
            lifecard.setLearnCount(lifecard.getLearnCount()+1);
            lifecardMapper.updateById(lifecard);
        }finally {
            //判断是否是自己的锁 并且还未释放
            if (lock.isLocked()){
                lock.unlock();
            }
        }

    }

    /**
     * 终身卡次数减1
     * @param lifecardId 终身卡id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reduceLifeCardCount(Integer lifecardId) throws Exception {
        //创建单锁
        RLock lock = redissonClient.getFairLock(CourseRedisKeyUtil.lockCurrentCountByCourseId(lifecardId));
        boolean isLock = lock.tryLock(10, TimeUnit.SECONDS);
        try {
            if (!isLock){
                throw new Exception("服务器繁忙请稍后再试");
            }
            //查询卡是否存在
            Lifecard lifecard = lifecardMapper.selectById(lifecardId);
            if (lifecard == null) throw new ProgressException(ProgressExceptionCode.PROGRESS_EXCEPTION_CODE_CARD_NOT_EXIST);
            //次数-1
            lifecard.setLearnCount(lifecard.getLearnCount()-1);
            lifecardMapper.updateById(lifecard);
        }finally {
            //判断是否是自己的锁 并且还未释放
            if (lock.isLocked()){
                lock.unlock();
            }
        }

    }
}
